rtc-da9052.c revision 7c994c08c376eb96503dc6a7110fda95e24dbdb1
1fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam/* 2fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * Real time clock driver for DA9052 3fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * 4fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * Copyright(c) 2012 Dialog Semiconductor Ltd. 5fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * 6fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * Author: Dajun Dajun Chen <dajun.chen@diasemi.com> 7fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * 8fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * This program is free software; you can redistribute it and/or modify 9fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * it under the terms of the GNU General Public License as published by 10fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * the Free Software Foundation; either version 2 of the License, or 11fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * (at your option) any later version. 12fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam * 13fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam */ 14fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 15fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam#include <linux/module.h> 16fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam#include <linux/platform_device.h> 17fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam#include <linux/rtc.h> 1811f54d05865c009a468e9d7adaa7414749daa6caSachin Kamat#include <linux/err.h> 19fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 20fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam#include <linux/mfd/da9052/da9052.h> 21fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam#include <linux/mfd/da9052/reg.h> 22fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 237c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech#define rtc_err(rtc, fmt, ...) \ 247c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech dev_err(rtc->da9052->dev, "%s: " fmt, __func__, ##__VA_ARGS__) 25fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 26fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstruct da9052_rtc { 27fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam struct rtc_device *rtc; 28fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam struct da9052 *da9052; 29fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}; 30fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 317c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olechstatic int da9052_rtc_enable_alarm(struct da9052_rtc *rtc, bool enable) 32fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{ 33fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam int ret; 34fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam if (enable) { 357c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech ret = da9052_reg_update(rtc->da9052, DA9052_ALARM_Y_REG, 367c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech DA9052_ALARM_Y_ALARM_ON|DA9052_ALARM_Y_TICK_ON, 377c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech DA9052_ALARM_Y_ALARM_ON); 38fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam if (ret != 0) 397c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_err(rtc, "Failed to enable ALM: %d\n", ret); 40fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam } else { 417c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech ret = da9052_reg_update(rtc->da9052, DA9052_ALARM_Y_REG, 427c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech DA9052_ALARM_Y_ALARM_ON|DA9052_ALARM_Y_TICK_ON, 0); 43fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam if (ret != 0) 447c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_err(rtc, "Write error: %d\n", ret); 45fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam } 46fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return ret; 47fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam} 48fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 49fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic irqreturn_t da9052_rtc_irq(int irq, void *data) 50fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{ 51fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam struct da9052_rtc *rtc = data; 52fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 537c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_update_irq(rtc->rtc, 1, RTC_IRQF | RTC_AF); 54fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 55fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return IRQ_HANDLED; 56fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam} 57fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 587c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olechstatic int da9052_read_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm) 59fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{ 60fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam int ret; 61fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam uint8_t v[5]; 62fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 637c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech ret = da9052_group_read(rtc->da9052, DA9052_ALARM_MI_REG, 5, v); 64fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam if (ret != 0) { 657c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_err(rtc, "Failed to group read ALM: %d\n", ret); 66fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return ret; 67fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam } 68fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 69fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc_tm->tm_year = (v[4] & DA9052_RTC_YEAR) + 100; 70fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc_tm->tm_mon = (v[3] & DA9052_RTC_MONTH) - 1; 71fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc_tm->tm_mday = v[2] & DA9052_RTC_DAY; 72fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc_tm->tm_hour = v[1] & DA9052_RTC_HOUR; 73fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc_tm->tm_min = v[0] & DA9052_RTC_MIN; 74fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 75fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam ret = rtc_valid_tm(rtc_tm); 76fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return ret; 77fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam} 78fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 797c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olechstatic int da9052_set_alarm(struct da9052_rtc *rtc, struct rtc_time *rtc_tm) 80fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{ 817c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech struct da9052 *da9052 = rtc->da9052; 827c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech unsigned long alm_time; 83fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam int ret; 84fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam uint8_t v[3]; 85fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 867c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech ret = rtc_tm_to_time(rtc_tm, &alm_time); 877c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech if (ret != 0) 887c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech return ret; 897c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech 907c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech if (rtc_tm->tm_sec > 0) { 917c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech alm_time += 60 - rtc_tm->tm_sec; 927c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_time_to_tm(alm_time, rtc_tm); 937c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech } 947c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech BUG_ON(rtc_tm->tm_sec); /* it will cause repeated irqs if not zero */ 957c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech 96fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc_tm->tm_year -= 100; 97fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc_tm->tm_mon += 1; 98fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 99fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam ret = da9052_reg_update(da9052, DA9052_ALARM_MI_REG, 100fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam DA9052_RTC_MIN, rtc_tm->tm_min); 101fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam if (ret != 0) { 1027c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_err(rtc, "Failed to write ALRM MIN: %d\n", ret); 103fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return ret; 104fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam } 105fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 106fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam v[0] = rtc_tm->tm_hour; 107fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam v[1] = rtc_tm->tm_mday; 108fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam v[2] = rtc_tm->tm_mon; 109fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 110fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam ret = da9052_group_write(da9052, DA9052_ALARM_H_REG, 3, v); 111fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam if (ret < 0) 112fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return ret; 113fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 114fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam ret = da9052_reg_update(da9052, DA9052_ALARM_Y_REG, 115fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam DA9052_RTC_YEAR, rtc_tm->tm_year); 116fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam if (ret != 0) 1177c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_err(rtc, "Failed to write ALRM YEAR: %d\n", ret); 118fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 119fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return ret; 120fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam} 121fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 1227c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olechstatic int da9052_rtc_get_alarm_status(struct da9052_rtc *rtc) 123fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{ 124fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam int ret; 125fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 1267c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech ret = da9052_reg_read(rtc->da9052, DA9052_ALARM_Y_REG); 127fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam if (ret < 0) { 1287c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_err(rtc, "Failed to read ALM: %d\n", ret); 129fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return ret; 130fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam } 1317c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech 1327c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech return !!(ret&DA9052_ALARM_Y_ALARM_ON); 133fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam} 134fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 135fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic int da9052_rtc_read_time(struct device *dev, struct rtc_time *rtc_tm) 136fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{ 137fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam struct da9052_rtc *rtc = dev_get_drvdata(dev); 138fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam uint8_t v[6]; 139fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam int ret; 140fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 141fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam ret = da9052_group_read(rtc->da9052, DA9052_COUNT_S_REG, 6, v); 142fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam if (ret < 0) { 1437c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_err(rtc, "Failed to read RTC time : %d\n", ret); 144fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return ret; 145fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam } 146fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 147fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc_tm->tm_year = (v[5] & DA9052_RTC_YEAR) + 100; 148fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc_tm->tm_mon = (v[4] & DA9052_RTC_MONTH) - 1; 149fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc_tm->tm_mday = v[3] & DA9052_RTC_DAY; 150fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc_tm->tm_hour = v[2] & DA9052_RTC_HOUR; 151fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc_tm->tm_min = v[1] & DA9052_RTC_MIN; 152fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc_tm->tm_sec = v[0] & DA9052_RTC_SEC; 153fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 154fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam ret = rtc_valid_tm(rtc_tm); 1557c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech return ret; 156fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam} 157fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 158fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic int da9052_rtc_set_time(struct device *dev, struct rtc_time *tm) 159fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{ 160fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam struct da9052_rtc *rtc; 161fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam uint8_t v[6]; 1627c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech int ret; 163fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 164fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc = dev_get_drvdata(dev); 165fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 166fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam v[0] = tm->tm_sec; 167fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam v[1] = tm->tm_min; 168fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam v[2] = tm->tm_hour; 169fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam v[3] = tm->tm_mday; 170fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam v[4] = tm->tm_mon + 1; 171fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam v[5] = tm->tm_year - 100; 172fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 1737c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech ret = da9052_group_write(rtc->da9052, DA9052_COUNT_S_REG, 6, v); 1747c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech if (ret < 0) 1757c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_err(rtc, "failed to set RTC time: %d\n", ret); 1767c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech return ret; 177fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam} 178fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 179fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic int da9052_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) 180fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{ 181fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam int ret; 182fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam struct rtc_time *tm = &alrm->time; 183fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam struct da9052_rtc *rtc = dev_get_drvdata(dev); 184fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 1857c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech ret = da9052_read_alarm(rtc, tm); 1867c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech if (ret < 0) { 1877c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_err(rtc, "failed to read RTC alarm: %d\n", ret); 188fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return ret; 1897c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech } 190fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 1917c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech alrm->enabled = da9052_rtc_get_alarm_status(rtc); 192fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return 0; 193fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam} 194fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 195fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic int da9052_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) 196fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{ 197fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam int ret; 198fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam struct rtc_time *tm = &alrm->time; 199fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam struct da9052_rtc *rtc = dev_get_drvdata(dev); 200fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 2017c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech ret = da9052_rtc_enable_alarm(rtc, 0); 202fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam if (ret < 0) 203fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return ret; 204fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 2057c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech ret = da9052_set_alarm(rtc, tm); 2067c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech if (ret < 0) 207fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return ret; 208fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 2097c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech ret = da9052_rtc_enable_alarm(rtc, 1); 210fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return ret; 211fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam} 212fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 213fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic int da9052_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) 214fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{ 215fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam struct da9052_rtc *rtc = dev_get_drvdata(dev); 216fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 2177c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech return da9052_rtc_enable_alarm(rtc, enabled); 218fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam} 219fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 220fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic const struct rtc_class_ops da9052_rtc_ops = { 221fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam .read_time = da9052_rtc_read_time, 222fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam .set_time = da9052_rtc_set_time, 223fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam .read_alarm = da9052_rtc_read_alarm, 224fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam .set_alarm = da9052_rtc_set_alarm, 225fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam .alarm_irq_enable = da9052_rtc_alarm_irq_enable, 226fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}; 227fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 2285a167f4543e45d45c5672a5cd6cb8ba5ddf4f3eaGreg Kroah-Hartmanstatic int da9052_rtc_probe(struct platform_device *pdev) 229fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam{ 230fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam struct da9052_rtc *rtc; 231fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam int ret; 232fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 233fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc = devm_kzalloc(&pdev->dev, sizeof(struct da9052_rtc), GFP_KERNEL); 234fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam if (!rtc) 235fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam return -ENOMEM; 236fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 237fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam rtc->da9052 = dev_get_drvdata(pdev->dev.parent); 238fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam platform_set_drvdata(pdev, rtc); 2397c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech 2407c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech ret = da9052_reg_write(rtc->da9052, DA9052_BBAT_CONT_REG, 0xFE); 2417c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech if (ret < 0) { 2427c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_err(rtc, 2437c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech "Failed to setup RTC battery charging: %d\n", ret); 2447c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech return ret; 2457c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech } 2467c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech 2477c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech ret = da9052_reg_update(rtc->da9052, DA9052_ALARM_Y_REG, 2487c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech DA9052_ALARM_Y_TICK_ON, 0); 2497c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech if (ret != 0) 2507c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_err(rtc, "Failed to disable TICKS: %d\n", ret); 2517c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech 252c2c0eed7f20cbfb20b346f1854afaf485bc6c207Anthony Olech ret = da9052_request_irq(rtc->da9052, DA9052_IRQ_ALARM, "ALM", 253925e8ea6bca2c9a590565634b27768d7042e089fAshish Jangam da9052_rtc_irq, rtc); 254fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam if (ret != 0) { 2557c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony Olech rtc_err(rtc, "irq registration failed: %d\n", ret); 256007def046711479f3d19bec4016b65fd73deed6cDevendra Naga return ret; 257fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam } 258fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 2593689cd741f627ee49a1a4d5c9aec49e120b6c291Jingoo Han rtc->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, 260fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam &da9052_rtc_ops, THIS_MODULE); 261dac30a9843f8a6007e9d25cad2b5735679041397Sachin Kamat return PTR_ERR_OR_ZERO(rtc->rtc); 262fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam} 263fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 264fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangamstatic struct platform_driver da9052_rtc_driver = { 265fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam .probe = da9052_rtc_probe, 266fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam .driver = { 267fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam .name = "da9052-rtc", 268fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam .owner = THIS_MODULE, 269fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam }, 270fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam}; 271fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 272fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangammodule_platform_driver(da9052_rtc_driver); 273fef931ff98fe78bea804d9b4c49d410a7a97988cAshish Jangam 2747c994c08c376eb96503dc6a7110fda95e24dbdb1Anthony OlechMODULE_AUTHOR("Anthony Olech <Anthony.Olech@diasemi.com>"); 275fef931ff98fe78bea804d9b4c49d410a7a97988cAshish JangamMODULE_DESCRIPTION("RTC driver for Dialog DA9052 PMIC"); 276fef931ff98fe78bea804d9b4c49d410a7a97988cAshish JangamMODULE_LICENSE("GPL"); 277fef931ff98fe78bea804d9b4c49d410a7a97988cAshish JangamMODULE_ALIAS("platform:da9052-rtc"); 278